<!DOCTYPE html>
<html lang="zh-hans">

<head>
    
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="HandheldFriendly" content="True" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<meta name="generator" content="Hugo 0.109.0">


<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dsrkafuu/dsr-cdn-main@1/images/favicons/dsrca.ico" />



<title>深度学习Step by Step - OffSummer</title>


<meta name="author" content="RQY" />


<meta name="description" content="A minimal Hugo theme with nice theme color." />


<meta name="keywords" content="mindspore, DL" />


<meta property="og:title" content="深度学习Step by Step" />
<meta name="twitter:title" content="深度学习Step by Step" />
<meta property="og:type" content="article" />
<meta property="og:url" content="/post/01-hello-world/" /><meta property="og:description" content="深度学习Step by Step
写在前面
本教程是有关深度学习的入门教程，基于一个国产的人工智能引擎，mindspore，主要参考了《深度学习》以及《动手学深度学习》，使用MindSpore实现了《动手学深度学习》中很多有用的练习，可以作为深度学习以及MindSpore的入门教程。" />
<meta name="twitter:description" content="深度学习Step by Step
写在前面
本教程是有关深度学习的入门教程，基于一个国产的人工智能引擎，mindspore，主要参考了《深度学习》以及《动手学深度学习》，使用MindSpore实现了《动手学深度学习》中很多有用的练习，可以作为深度学习以及MindSpore的入门教程。" /><meta property="og:image" content="/img/og.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="/img/og.png" /><meta property="article:published_time" content="2022-10-15T23:00:00+08:00" /><meta property="article:modified_time" content="2022-10-15T23:00:00+08:00" />


<style>
    @media (prefers-color-scheme: dark) {
        body[data-theme='auto'] img {
            filter: brightness(60%);
        }
    }

    body[data-theme='dark'] img {
        filter: brightness(60%);
    }
</style>




<link rel="stylesheet" href="/assets/css/fuji.min.b4a21b5d3eb1d0a51297e31230a65fc25e387843e45ec3a2d9176cd8d163c216d99b9b13a618b28f537c3b559ec8a408183b0fbfad48daddb9befa7d3ef90eed.css" integrity="sha512-tKIbXT6x0KUSl&#43;MSMKZfwl44eEPkXsOi2Rds2NFjwhbZm5sTphiyj1N8O1WeyKQIGDsPv61I2t25vvp9PvkO7Q==" />








</head>

<body
  data-theme="auto"
  data-theme-auto='true'
  >
    <script data-cfasync="false">
  
  var fujiThemeData = localStorage.getItem('fuji_data-theme');
  
  if (!fujiThemeData) {
    localStorage.setItem('fuji_data-theme', 'auto');
  } else {
    
    if (fujiThemeData !== 'auto') {
      document.body.setAttribute('data-theme', fujiThemeData === 'dark' ? 'dark' : 'light');
    }
  }
</script>

    <header>
    <div class="container-lg clearfix">
        <div class="col-12 header">
            <a class="title-main" href="/">OffSummer</a>
            
            <span class="title-sub">Summer is going, but autumn does not come yet.</span>
            
        </div>
    </div>
</header>

    <main>
        <div class="container-lg clearfix">
            
            <div class="col-12 col-md-9 float-left content">
                
<article>
    
    <h2 class="post-item post-title">
        <a href="/post/01-hello-world/">深度学习Step by Step</a>
    </h2>
    <div class="post-item post-meta">
        <span><i class="iconfont icon-today-sharp"></i>&nbsp;2022-10-15</span>

<span><i class="iconfont icon-file-tray-sharp"></i>&nbsp;2320 字</span>
<span><i class="iconfont icon-time-sharp"></i>&nbsp;5 分钟</span>
<span><i class="iconfont icon-pricetags-sharp"></i>&nbsp;<a href="/tags/mindspore">mindspore</a>&nbsp;<a href="/tags/dl">DL</a>&nbsp;</span>

    </div>
    
    <div class="post-content markdown-body">
        <h1 id="深度学习step-by-step">深度学习Step by Step</h1>
<h2 id="写在前面">写在前面</h2>
<p>本教程是有关深度学习的入门教程，基于一个国产的人工智能引擎，<a href="https://www.mindspore.cn/" target="_blank">mindspore</a>，主要参考了《深度学习》以及《动手学深度学习》，使用MindSpore实现了《动手学深度学习》中很多有用的练习，可以作为深度学习以及MindSpore的入门教程。</p>
<p>阅读本教程需要有一定的Python基础。</p>
<p>你可以访问这个连接进行下载MindSpore：https://www.mindspore.cn/install。</p>
<p>所有代码可以在<a href="https://gitee.com/ruqy/deep-learning-step-by-step" target="_blank">仓库</a>中获取。</p>
<h2 id="线性神经网络">线性神经网络</h2>
<p>在历史上，神经网络有三次浪潮，其一是随着控制论的发展，奠定了神经网络的基本结构（感知机）；第二次是联结主义的发展，使用了反向传播；深度学习则是近十几年发展而来，主要的代表有卷积神经网络等。</p>
<p>下面通过numpy来实现线性回归，以介绍深度学习的基本知识。</p>
<h3 id="产生数据">产生数据</h3>
<p>假设有一个线性生成器，以下式产生数值，其实W与B是未知的矩阵，N是高斯分布的噪声</p>
<p>$$
Y = W X^T + B + N
$$</p>
<p>我们通过下面这个程序来生成n个数据，并添加均值为0，方差为0.01的噪声。</p>
<pre><code class="language-python">def synthetic_data(w, b, n):
    x = np.random.normal(0, 1, (n, 1))
    y = np.matmul(x, w) + b
    # add noise
    y += np.random.normal(0, 0.01, y.shape)
    return x, y
</code></pre>
<h3 id="线性网络">线性网络</h3>
<p>我们要通过数据来估计出W与B的取值，使用线性网络</p>
<p>$$
\hat y = \hat w x^T + \hat b
$$</p>
<p>可以通过下面这个式子来实现</p>
<pre><code class="language-python">def linreg(x, w, b):
    return np.matmul(w, x.T) + b
</code></pre>
<h3 id="损失函数">损失函数</h3>
<p>我们需要评估我们与目标函数之间的误差，并称这个函数为损失函数。在这里，我们采用平方误差（也叫L2损失）来衡量我们的预测函数与目标函数之间的差距。注意到我们对目标函数的$X$与$B$都是未知的，所以我们只能在给定$X$的条件下，确定预测函数输出的$\hat y$与目标函数输出的真实$y$之间的差距，即</p>
<p>$$
Loss(y, \hat y) = \frac{(\hat y - y)^2}2
$$</p>
<p>上式需要除二是因为求导后的表达式更简洁。我们通过下面的程序实现：</p>
<pre><code class="language-python">def squared_loss(y_hat, y):
    return np.square(y_hat - y)/2
</code></pre>
<h3 id="批量计算">批量计算</h3>
<p>我们通过来打乱数据，提高计算速度。</p>
<p>以下是实现的代码，首先，我们要产生一组索引，通过<code>np.random.shuffle</code>将其打乱，然后以<code>batch_size</code>为一个批次，用<code>np.mat</code>生成将一系列矩阵作为索引，最后通过<code>yield</code>返回数据。</p>
<pre><code class="language-python">def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    np.random.shuffle(indices)
    for i in range(0, num_examples, batch_size):
        batch_indices = np.mat(indices[i:min(i + batch_size, num_examples)])
        yield features[batch_indices, :], labels[:, batch_indices]
</code></pre>
<h3 id="优化器">优化器</h3>
<h4 id="梯度">梯度</h4>
<p>我们初始化设置的$W$是高斯分布的，$B$为0，可以想到，当我们输入一个$X$，此时线性网络的输出结果$\hat y$与真实值之间存在有较大的差距，所以我们需要通过某种方法来更新$W$与$B$。</p>
<p>作为线性函数时，我们很容易想到使用最小二乘法来计算最佳的$W$与$B$，但最小二乘法并不是什么时候都能够使用的。在深度学习中，我们由远及近，通过计算梯度的方式，来更新网络的参数。</p>
<p>什么是梯度呢？用一个简单的例子，比如有个函数，$y=\frac 1 2 x^2$，我们要寻找x值的最小值，虽然从数学上我们能很容易地知道该函数的最小值是0，但假设我们现在还不知道，如何寻找该函数的最小值呢？根据微积分，加入我们有一个点$x_0$，我们将其带入函数中求导，得到$y&rsquo;=x_0$，如果$x_0&gt;0$，则$y&rsquo;&gt;0$，此时往$y&rsquo;$减小的方向（即$-y&rsquo;$方向）更新$x_0$，就有希望达到极小值；如果$x_0&lt;0$，则$y&rsquo;&lt;0$，此时往$y&rsquo;$增大的方向（即$-y&rsquo;$方向）更新$x_0$，就有希望达到极小值。从上面的例子看出，不管如何，往导数方向相反的方向，就有可能找到函数的极小值。</p>
<p>梯度，则是一元函数导数的推广，即对多元函数来说，梯度方向是函数值增长的方向；而梯度的反方向，有可能能够找到函数的极小值。</p>
<h4 id="链式法则">链式法则</h4>
<p>对多元函数来说，可以链式法则进行求导。</p>
<h4 id="反向传播">反向传播</h4>
<p>我们将由数据$x$得到$\hat y$的过程，称为正向传播，此时我们可以计算出梯度。根据得到的梯度，反向更新网络的参数，该过程被称为反向传播。</p>
<h4 id="随机梯度下降sgd">随机梯度下降（SGD）</h4>
<p>我们要使$\hat y \to y$，等价于使损失函数最小化，也就是对损失函数求$W$与$B$的梯度，来更新$W$与$B$的权重。</p>
<p>所以，我们根据以下式子来更新线性函数的$W$与$B$</p>
<p>$$
\hat w - lr * \frac{\partial Loss}{\partial \hat w}  \to \hat w
$$</p>
<p>$$
\hat b - lr * \frac{\partial Loss}{\partial \hat b}  \to \hat b
$$</p>
<p>式中的$lr$是学习率，目的是将梯度的大小进行缩放，避免以太大的范围更新权限。</p>
<p>首先我们来计算一下$W$与$B$的梯度，根据损失函数，将$\hat y$代入，有</p>
<p>$$
Loss(y, x, b) = \frac{(\hat w \times x + \hat b - y)^2}2
$$</p>
<p>如果我们对他求导，可以得到以下两个式子</p>
<p>$$
\frac{\partial Loss}{\partial \hat w}= (\hat w \times x + \hat b - y)\times x = (\hat y - y)\times x
$$</p>
<p>$$
\frac{\partial Loss}{\partial \hat b} = \hat w \times x + \hat b - y) = (\hat y - y)
$$</p>
<p>我们通过下面的代码实现上述的过程。</p>
<pre><code class="language-python">def linreg_sgd(w, b, x, y, lr, batch_size):
    # manual calculate the gradient of squared loss
    y_hat = linreg(x.squeeze(axis=0), w, b)
    grad_w = (y_hat - y.squeeze(axis=0))*x.squeeze(axis=0)
    grad_b = (y_hat - y.squeeze(axis=0))
    grad_b = grad_b.sum(axis=1)
    new_w = w-lr*grad_w/batch_size
    new_b = b-lr*grad_b/batch_size
    return new_w, new_b
</code></pre>
<p>原理上，我们要在所有的样本中计算出梯度再进行更新，但现在我们只计算了一个batch size样本的梯度就对网络参数进行了更新，这个batch size样本的选择具有一定的随机性，所以称为随机梯度下降。</p>
<h3 id="程序逻辑">程序逻辑</h3>
<p>首先，我们设置真实的分布</p>
<pre><code class="language-python">    true_w = np.mat([2, -3.4])
    true_b = np.array([4.2])
</code></pre>
<p>然后，生成1000个样本数据</p>
<pre><code class="language-python">    features, labels = synthetic_data(true_w, true_b, 1000)
</code></pre>
<p>设置批量为10，学习率0.03，训练三轮，</p>
<pre><code class="language-python">    batch_size = 10
    lr = 0.03
    epochs = 3
</code></pre>
<p>以均值为0，方差为0.01设置需要训练的w，以0设置b。</p>
<pre><code class="language-python">    w = np.random.normal(0, 0.01, (1, 2))
    b = np.zeros((1, 1))
    print(f'Initial w={w}, b={b}')
</code></pre>
<p>设置网络为线性网络，损失函数为平方差函数。</p>
<pre><code class="language-python">    net = linreg
    loss = squared_loss
</code></pre>
<p>最后一步，输入数据，获取梯度，更新$w$，$b$的值，计算损失函数。</p>
<pre><code class="language-python">    for epoch in range(epochs):
        for x, y in data_iter(batch_size, features, labels):
            w, b = linreg_sgd(w, b, x, y, lr, batch_size)
        train_loss = loss(net(features, w, b), labels)
        print(f'In epoch {epoch + 1}, loss is {float(train_loss.mean()):f}')
</code></pre>
<p>最后我们可以得到估计的$w$与$b$。</p>
<pre><code class="language-python">    print(f'estimate w is {w}, b is {b}')
    print(f'estimate error is that w is {w-true_w} and b is {b-true_b}')
</code></pre>
<h3 id="实现结果">实现结果</h3>
<p>以下是程序的输出结果</p>
<pre><code class="language-shell">Initial w=[[-0.0204044 -0.0061789]], b=[[0.]]
In epoch 1, loss is 0.035662
In epoch 2, loss is 0.000127
In epoch 3, loss is 0.000049
estimate w is [[ 1.9999425  -3.39916696]], b is [[4.19945344]]
estimate error is that w is [[-5.74996689e-05  8.33035609e-04]] and b is [[-0.00054656]]
</code></pre>
    </div>
</article>




            </div>
            <aside class="col-12 col-md-3 float-left sidebar">
    
    <div class="sidebar-item sidebar-pages">
        <h3>页面</h3>
        <ul>
            
            <li>
                <a href="/">Home</a>
            </li>
            
            <li>
                <a href="/archives/">Archives</a>
            </li>
            
            <li>
                <a href="/about/">About</a>
            </li>
            
            <li>
                <a href="/search/">Search</a>
            </li>
            
            <li>
                <a href="/index.xml">RSS</a>
            </li>
            
        </ul>
    </div>
    
    <div class="sidebar-item sidebar-links">
        <h3>链接</h3>
        <ul>
            
            <li>
                <a href="https://github.com/ruaqy" target="_blank"><span>GitHub</span></a>
            </li>
            
            <li>
                <a href="https://gitee.com/ruqy" target="_blank"><span>Gitee</span></a>
            </li>
            
            <li>
                <a href="https://space.bilibili.com/13382902" target="_blank"><span>Bilibili</span></a>
            </li>
            
        </ul>
    </div>
    
    <div class="sidebar-item sidebar-tags">
        <h3>标签</h3>
        <div>
            
            <span>
                <a href="/tags/dl/">DL</a>
            </span>
            
            <span>
                <a href="/tags/make-up/">Make Up</a>
            </span>
            
            <span>
                <a href="/tags/matlab/">MATLAB</a>
            </span>
            
            <span>
                <a href="/tags/mindspore/">mindspore</a>
            </span>
            
            <span>
                <a href="/tags/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/">机器学习</a>
            </span>
            
        </div>
    </div>
    <div class="sidebar-item sidebar-toc">
        <h3>目录</h3><nav id="TableOfContents">
  <ul>
    <li><a href="#写在前面">写在前面</a></li>
    <li><a href="#线性神经网络">线性神经网络</a>
      <ul>
        <li><a href="#产生数据">产生数据</a></li>
        <li><a href="#线性网络">线性网络</a></li>
        <li><a href="#损失函数">损失函数</a></li>
        <li><a href="#批量计算">批量计算</a></li>
        <li><a href="#优化器">优化器</a></li>
        <li><a href="#程序逻辑">程序逻辑</a></li>
        <li><a href="#实现结果">实现结果</a></li>
      </ul>
    </li>
  </ul>
</nav></div>
</aside>

        </div>
        <div class="btn">
    <div class="btn-menu" id="btn-menu">
        <i class="iconfont icon-grid-sharp"></i>
    </div>
    <div class="btn-toggle-mode">
        <i class="iconfont icon-contrast-sharp"></i>
    </div>
    <div class="btn-scroll-top">
        <i class="iconfont icon-chevron-up-circle-sharp"></i>
    </div>
</div>
<aside class="sidebar-mobile" style="display: none;">
  <div class="sidebar-wrapper">
    
    <div class="sidebar-item sidebar-pages">
        <h3>页面</h3>
        <ul>
            
            <li>
                <a href="/">Home</a>
            </li>
            
            <li>
                <a href="/archives/">Archives</a>
            </li>
            
            <li>
                <a href="/about/">About</a>
            </li>
            
            <li>
                <a href="/search/">Search</a>
            </li>
            
            <li>
                <a href="/index.xml">RSS</a>
            </li>
            
        </ul>
    </div>
    
    <div class="sidebar-item sidebar-links">
        <h3>链接</h3>
        <ul>
            
            <li>
                <a href="https://github.com/ruaqy" target="_blank"><span>GitHub</span></a>
            </li>
            
            <li>
                <a href="https://gitee.com/ruqy" target="_blank"><span>Gitee</span></a>
            </li>
            
            <li>
                <a href="https://space.bilibili.com/13382902" target="_blank"><span>Bilibili</span></a>
            </li>
            
        </ul>
    </div>
    
    <div class="sidebar-item sidebar-tags">
        <h3>标签</h3>
        <div>
            
            <span>
                <a href="/tags/dl/">DL</a>
            </span>
            
            <span>
                <a href="/tags/make-up/">Make Up</a>
            </span>
            
            <span>
                <a href="/tags/matlab/">MATLAB</a>
            </span>
            
            <span>
                <a href="/tags/mindspore/">mindspore</a>
            </span>
            
            <span>
                <a href="/tags/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/">机器学习</a>
            </span>
            
        </div>
    </div>
    
    
    
    <div class="sidebar-item sidebar-toc">
        <h3>目录</h3>
        <nav id="TableOfContents">
  <ul>
    <li><a href="#写在前面">写在前面</a></li>
    <li><a href="#线性神经网络">线性神经网络</a>
      <ul>
        <li><a href="#产生数据">产生数据</a></li>
        <li><a href="#线性网络">线性网络</a></li>
        <li><a href="#损失函数">损失函数</a></li>
        <li><a href="#批量计算">批量计算</a></li>
        <li><a href="#优化器">优化器</a></li>
        <li><a href="#程序逻辑">程序逻辑</a></li>
        <li><a href="#实现结果">实现结果</a></li>
      </ul>
    </li>
  </ul>
</nav>
    </div>
    
    
  </div>
</aside>
    </main>

    <footer>
    <div class="container-lg clearfix">
        <div class="col-12 footer">
            
            <p>
                除特殊注明部分，本站内容采用 <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 进行许可。
            </p>
            
            <span>&copy; 2023-2023
                <a href="/">RQY</a>
                 | <a href="https://github.com/dsrkafuu/hugo-theme-fuji">Source code</a> 
                | 基于 <a href="https://github.com/dsrkafuu/hugo-theme-fuji/"
                   target="_blank">Fuji-v2</a> &amp; <a href="https://gohugo.io/"
                                                    target="_blank">Hugo</a> 构建
            </span>
        </div>
    </div>
</footer>

    
<script defer src="https://cdn.jsdelivr.net/npm/medium-zoom@1.0.6/dist/medium-zoom.min.js" integrity="sha512-N9IJRoc3LaP3NDoiGkcPa4gG94kapGpaA5Zq9/Dr04uf5TbLFU5q0o8AbRhLKUUlp8QFS2u7S+Yti0U7QtuZvQ==" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/lazysizes@5.3.2/lazysizes.min.js" integrity="sha512-q583ppKrCRc7N5O0n2nzUiJ+suUv7Et1JGels4bXOaMFQcamPk9HjdUknZuuFjBNs7tsMuadge5k9RzdmO+1GQ==" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/components/prism-core.min.js" integrity="sha512-LCKPTo0gtJ74zCNMbWw04ltmujpzSR4oW+fgN+Y1YclhM5ZrHCZQAJE4quEodcI/G122sRhSGU2BsSRUZ2Gu3w==" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/plugins/autoloader/prism-autoloader.min.js" integrity="sha512-GP4x8UWxWyh4BMbyJGOGneiTbkrWEF5izsVJByzVLodP8CuJH/n936+yQDMJJrOPUHLgyPbLiGw2rXmdvGdXHA==" crossorigin="anonymous"></script>



<script defer src="/assets/js/fuji.min.645f1123be695831f419ab54c1bcba327325895c740014006e57070d4f3e5d6b553e929c4b46f40ea707249e9c7f7c2a446d32a39ce7319f80a34525586a8e0f.js" integrity="sha512-ZF8RI75pWDH0GatUwby6MnMliVx0ABQAblcHDU8&#43;XWtVPpKcS0b0DqcHJJ6cf3wqRG0yo5znMZ&#43;Ao0UlWGqODw=="></script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.css" integrity="sha512-07YhC3P4/vS5HdgGuNAAeIxb5ee//efgRNo5AGdMtqFBUPYOdQG/sDK0Nl5qNq94kdEk/Pvu8pmN4GYUeucUkw==" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.min.js" integrity="sha512-aMDiFsrEV3KzAn9EHwyBRS7y1APjZWt/Z/73ukLN2Ca2KcGGzlOQFQSnfOdnEcehpwMaQ8edlDB/0cMX2GsHbg==" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/contrib/auto-render.min.js" integrity="sha512-ZA/RPrAo88DlwRnnoNVqKINnQNcWERzRK03PDaA4GIJiVZvGFIWQbdWCsUebMZfkWohnfngsDjXzU6PokO4jGw==" crossorigin="anonymous"></script>
<script>
  renderMathInElement(document.querySelector('div.content'), {
    delimiters: [
      { left: '$$', right: '$$', display: true },
      { left: '\\[', right: '\\]', display: true },
      { left: '$', right: '$', display: false },
      { left: '\\(', right: '\\)', display: false },
    ],
  });
</script>




</body>

</html>
